using System;
using System.IO;
using System.Text.Json;
using Avalonia;
using Avalonia.Interactivity;
using DocumentMaking.FluentNext.Dialogs;
using DocumentMaking.FluentNext.Themes;
using DocumentMaking.FluentNext.ViewModels;
using DocumentMaking.Lib.JsonContexts;
using DocumentMaking.Lib.Models;
using FluentAvalonia.UI.Controls;
using FluentAvalonia.UI.Windowing;

namespace DocumentMaking.FluentNext.Views;

public partial class MainWindow : AppWindow
{
    private SettingModel? Model { get; set; }
    private DocumentMakingViewModel Doc { get; } = new();

    public MainWindow()
    {
        InitializeComponent();
        TitleBar.ExtendsContentIntoTitleBar = true;
        TitleBar.TitleBarHitTestType = TitleBarHitTestType.Complex;

        var settingModel = SettingModel.Default;

        if (File.Exists("Setting.json"))
            settingModel = JsonSerializer.Deserialize(
                File.ReadAllText("Setting.json"), SourceGenerationContext.Default.SettingModel);
        else
        {
            var stream = File.Create("Setting.json");
            stream.Dispose();
            File.WriteAllText("Setting.json", JsonSerializer.Serialize(
                settingModel, typeof(SettingModel), SourceGenerationContext.Default));
        }

        Model = settingModel;
        Change(settingModel);
    }

    #region Init

    protected override void OnClosed(EventArgs e)
    {
        base.OnClosed(e);
        if (Model == null) return;
        File.WriteAllText("Setting.json", JsonSerializer.Serialize(
            Model, typeof(SettingModel), SourceGenerationContext.Default));
    }

    private void Change(SettingModel? settingModel)
    {
        Doc.Init(settingModel);

        if (settingModel == null || string.IsNullOrEmpty(settingModel.ThemeMode))
        {
            Control.Content = new NextThemeView() { DataContext = Doc };
            return;
        }

        Control.Content = settingModel.ThemeMode switch
        {
            "Carousel" => new CarouselThemeView(){ DataContext = Doc },
            "TabStrip" => new TabStripThemeView(){ DataContext = Doc },
            "Setting" => new SettingThemeView(){ DataContext = Doc },
            "Next" => new NextThemeView(){ DataContext = Doc },
            _ => new NextThemeView(){ DataContext = Doc }
        };
    }

    private void Change(string? theme)
    {
        Doc.Init(Model);
        
        if (string.IsNullOrEmpty(theme))
        {
            Control.Content = new NextThemeView() { DataContext = Doc };
            return;
        }
        
        Control.Content = theme switch
        {
            "Carousel" => new CarouselThemeView(){ DataContext = Doc },
            "TabStrip" => new TabStripThemeView(){ DataContext = Doc },
            "Setting" => new SettingThemeView(){ DataContext = Doc },
            "Next" => new NextThemeView(){ DataContext = Doc },
            _ => new NextThemeView(){ DataContext = Doc }
        };
    }

    #endregion

    private async void SettingClick(object? sender, RoutedEventArgs e)
    {
        var td = new TaskDialog()
        {
            Title = "文档生成工具",
            Content = new SettingDialog(Model),
            Header = "设置",
            IconSource = new SymbolIconSource() { Symbol = Symbol.SettingsFilled },
            FooterVisibility = TaskDialogFooterVisibility.Never,
            Buttons =
            {
                new TaskDialogButton("保存", true),
                new TaskDialogButton("应用", null),
                new TaskDialogButton("取消", false)
            },
            XamlRoot = (Visual)VisualRoot!
        };
        td.Closing += (dialog, args) =>
        {
            if (dialog.Content is not SettingDialog settingDialog) return;
            var model = settingDialog.Done();
            if (args.Result is null)
            {
                Change(model);
                return;
            }

            if (args.Result is not bool b)
            {
                var a = model.ThemeMode;
                if (a != Model?.ThemeMode)
                    Change(a);
                return;
            }

            if (!b) return;
            Model = model;
            Change(Model);
        };
        await td.ShowAsync();
    }
}